package com.example.sxmall.service.handler;

import com.alibaba.fastjson.JSON;
import com.whhim.hxh.auth.Authentication;
import com.whhim.hxh.auth.UserInfo;
import com.whhim.hxh.constant.ValidStatusConstant;
import com.whhim.hxh.controller.order.req.confirm.OrderCommitReq;
import com.whhim.hxh.controller.order.req.confirm.OrderConfirmReq;
import com.whhim.hxh.controller.order.vo.confirm.ConfirmOrderVO;
import com.whhim.hxh.controller.order.vo.confirm.StoreProductVO;
import com.whhim.hxh.controller.order.vo.detail.ReceivedAddressVO;
import com.whhim.hxh.controller.product.vo.ProductVO;
import com.whhim.hxh.controller.store.vo.StoreVO;
import com.whhim.hxh.exception.AppException;
import com.whhim.hxh.pojo.entity.HxhMaterialEntity;
import com.whhim.hxh.pojo.entity.HxhOrderDetailEntity;
import com.whhim.hxh.pojo.entity.HxhOrderEntity;
import com.whhim.hxh.redis.RedisService;
import com.whhim.hxh.redis.prefix.ShopCartKey;
import com.whhim.hxh.service.order.dto.OrderParamDTO;
import com.whhim.hxh.service.order.enums.OrderStatusEnum;
import com.whhim.hxh.service.product.CommonProductService;
import com.whhim.hxh.service.product.enums.ProductEnums;
import com.whhim.hxh.service.shopCart.constant.ShopCartMessageConstant;
import com.whhim.hxh.service.shopCart.dto.ShopCartDTO;
import com.whhim.hxh.util.OrderUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 购物车确认订单/提交订单 处理器 处理购物车商品信息/删除购物车商品信息
 * @Author whh-yt
 * @Date 2022/3/9 4:12 下午
 */
@Slf4j
@Component
public class ShopCartHandler {

    @Autowired
    private RedisService redisService;
    @Autowired
    private CommonProductService commonProductService;

    /**
     * 购物车 确认订单 处理数据
     */
    public void confirmOrder(OrderConfirmReq orderConfirmReq, ConfirmOrderVO confirmOrderVO) {
        UserInfo userInfo = Authentication.getUserInfo();
        ShopCartDTO shopCartDTO = redisService.get(ShopCartKey.SHOP_CART_KEY, userInfo.getUnionId(), ShopCartDTO.class);
        shopCartDTO.getStoreProductList().forEach(storeProductVO -> storeProductVO.getProductList().removeIf(item -> !item.getCheck()));
        shopCartDTO.getStoreProductList().removeIf(item -> CollectionUtils.isEmpty(item.getProductList()));
        confirmOrderVO.setStoreProductList(shopCartDTO.getStoreProductList());
    }

    /**
     * 购物车提交订单 组装订单数据
     */
    public List<OrderParamDTO> commitOrder(OrderCommitReq orderCommitReq) {
        UserInfo userInfo = Authentication.getUserInfo();
        ShopCartDTO shopCartDTO = redisService.get(ShopCartKey.SHOP_CART_KEY, userInfo.getUnionId(), ShopCartDTO.class);
        shopCartDTO.getStoreProductList().forEach(storeProductVO -> storeProductVO.getProductList().removeIf(item -> !item.getCheck()));
        shopCartDTO.getStoreProductList().removeIf(item -> CollectionUtils.isEmpty(item.getProductList()));
        List<StoreProductVO> storeProductList = shopCartDTO.getStoreProductList();
        if (CollectionUtils.isEmpty(storeProductList)) {
            log.error("ShopCartHandler#commitOrder, userinfo:{}", JSON.toJSONString(userInfo));
            throw new AppException(ShopCartMessageConstant.COMMIT_ORDER_ERROR);
        }
        return processShopCartOrderList(orderCommitReq, storeProductList);
    }

    private List<OrderParamDTO> processShopCartOrderList(OrderCommitReq orderCommitReq, List<StoreProductVO> storeProductList) {
        List<String> skuCodeList = storeProductList.stream().flatMap(storeProductVO -> storeProductVO.getProductList().stream())
                .map(ProductVO::getSkuCode).collect(Collectors.toList());
        List<HxhMaterialEntity> materialEntityList = commonProductService.listMaterialBySkuList(skuCodeList);
        if (CollectionUtils.isEmpty(materialEntityList)) {
            throw new AppException(ShopCartMessageConstant.COMMIT_ORDER_ERROR);
        }
        boolean onShelf = materialEntityList.stream().anyMatch(item -> item.getOnShelf().equals(ProductEnums.ProductOnShelfEnum.ON_SHELF.getType()));
        if (!onShelf) {
            throw new AppException(ShopCartMessageConstant.PRODUCT_OFF_SHELF);
        }
        List<OrderParamDTO> orderParamDTOList = new ArrayList<>();
        storeProductList.forEach(storeProductVO -> orderParamDTOList.add(this.buildOrderEntity(orderCommitReq, storeProductVO, materialEntityList)));
        return orderParamDTOList;
    }


    /**
     * 对商详下单进行组装插入数据
     */
    public final OrderParamDTO buildOrderEntity(OrderCommitReq orderCommitReq,
                                                StoreProductVO storeProductVO,
                                                List<HxhMaterialEntity> materialEntityList) {
        UserInfo userInfo = Authentication.getUserInfo();
        ReceivedAddressVO receivedAddress = orderCommitReq.getReceivedAddress();
        StoreVO store = storeProductVO.getStore();
        List<ProductVO> productList = storeProductVO.getProductList();
        BigDecimal orderAmount = productList.stream()
                .map(item -> item.getUnitPrice().multiply(BigDecimal.valueOf(item.getBuyCount())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        OrderParamDTO orderParamDTO = new OrderParamDTO();
        String orderNo = OrderUtils.createOrderNo();
        // TODO 如果加营销 在此 计算 优惠券 活动金额，积分花费等
        HxhOrderEntity hxhOrderEntity = new HxhOrderEntity();
        hxhOrderEntity.setOrderNo(orderNo);
        hxhOrderEntity.setOrderStatus(OrderStatusEnum.WAIT_PAY.getType());
        hxhOrderEntity.setBuyerCode(userInfo.getUnionId());
        hxhOrderEntity.setContacts(receivedAddress.getContacts());
        hxhOrderEntity.setTelephone(receivedAddress.getTelephone());
        hxhOrderEntity.setStoreId(store.getId());
        hxhOrderEntity.setPlatformSource(userInfo.getPlatformSource());
        hxhOrderEntity.setPayPattern(orderCommitReq.getPayPattern());
        hxhOrderEntity.setPayStatus(0);
        hxhOrderEntity.setOrderAmount(orderAmount);
        hxhOrderEntity.setDiscountAmount(BigDecimal.ZERO);
        hxhOrderEntity.setPayAmount(orderAmount);
        hxhOrderEntity.setFreightAmount(BigDecimal.ZERO);
        hxhOrderEntity.setCreateTime(LocalDateTime.now());
        hxhOrderEntity.setAddressId(receivedAddress.getId());
        hxhOrderEntity.setProvinceCode(receivedAddress.getProvinceCode());
        hxhOrderEntity.setProvinceName(receivedAddress.getProvinceName());
        hxhOrderEntity.setCityCode(receivedAddress.getCityCode());
        hxhOrderEntity.setCityName(receivedAddress.getCityName());
        hxhOrderEntity.setCountyCode(receivedAddress.getCountyCode());
        hxhOrderEntity.setCountyName(receivedAddress.getCountyName());
        hxhOrderEntity.setMapPosition(receivedAddress.getMapPosition());
        hxhOrderEntity.setAddress(receivedAddress.getAddress());
        hxhOrderEntity.setInvoice(0);
        hxhOrderEntity.setInvoiceChange(0);
        hxhOrderEntity.setEvaluation(0);
        hxhOrderEntity.setCommission(0);
        hxhOrderEntity.setFreezeDate(0);
        hxhOrderEntity.setRightsProtection(0);
        hxhOrderEntity.setOrderType(0);
        hxhOrderEntity.setNote(orderCommitReq.getNote());
        hxhOrderEntity.setDiscountDetails("");
        hxhOrderEntity.setCouponAmount(BigDecimal.ZERO);
        hxhOrderEntity.setActivityAmount(BigDecimal.ZERO);
        hxhOrderEntity.setPointAmount(BigDecimal.ZERO);
        hxhOrderEntity.setPointExpend(0);
        hxhOrderEntity.setCancelNote("");
        hxhOrderEntity.setCancelBy("");
        hxhOrderEntity.setIsDeleted(ValidStatusConstant.YES_INT);
        hxhOrderEntity.setOperBy("");
        hxhOrderEntity.setOperTime(LocalDateTime.now());

        int itemNo = 1;
        List<HxhOrderDetailEntity> orderDetailList = new ArrayList<>();
        for (ProductVO productVO : productList) {
            HxhOrderDetailEntity hxhOrderDetailEntity = new HxhOrderDetailEntity();
            hxhOrderDetailEntity.setOrderNo(orderNo);
            hxhOrderDetailEntity.setItemNo(itemNo++);
            hxhOrderDetailEntity.setProductStatus(OrderStatusEnum.WAIT_PAY.getType());
            hxhOrderDetailEntity.setStoreId(store.getId());
            hxhOrderDetailEntity.setSpuCode(productVO.getSpuCode());
            hxhOrderDetailEntity.setSkuCode(productVO.getSkuCode());
            hxhOrderDetailEntity.setMaterialCode(productVO.getMaterialCode());
            hxhOrderDetailEntity.setUnit(productVO.getUnit());
            hxhOrderDetailEntity.setUnitPrice(productVO.getUnitPrice());
            hxhOrderDetailEntity.setBuyNum(productVO.getBuyCount());
            hxhOrderDetailEntity.setProductAmount(productVO.getUnitPrice().multiply(BigDecimal.valueOf(productVO.getBuyCount())));
            hxhOrderDetailEntity.setDiscountAmount(BigDecimal.ZERO);
            hxhOrderDetailEntity.setFreightAmount(BigDecimal.ZERO);
            hxhOrderDetailEntity.setPayAmount(productVO.getUnitPrice().multiply(BigDecimal.valueOf(productVO.getBuyCount())));
            hxhOrderDetailEntity.setRefundAmount(BigDecimal.ZERO);
            hxhOrderDetailEntity.setDeliverNum(0);
            hxhOrderDetailEntity.setReceiveNum(0);
            hxhOrderDetailEntity.setRefundNum(0);
            hxhOrderDetailEntity.setRefundTimes(0);
            hxhOrderDetailEntity.setRefuseTimes(0);
            hxhOrderDetailEntity.setProductType(0);
            hxhOrderDetailEntity.setDiscountDetails("");
            hxhOrderDetailEntity.setCouponAmount(BigDecimal.ZERO);
            hxhOrderDetailEntity.setActivityAmount(BigDecimal.ZERO);
            hxhOrderDetailEntity.setPointAmount(BigDecimal.ZERO);
            hxhOrderDetailEntity.setPointExpend(0);
            // 购物车存储该商品信息 shareId 是否为分享
            hxhOrderDetailEntity.setShareId(productVO.getShareId());
            hxhOrderDetailEntity.setOperTime(LocalDateTime.now());
            orderDetailList.add(hxhOrderDetailEntity);
        }

        orderParamDTO.setOrderInfo(hxhOrderEntity);
        orderParamDTO.setOrderDetailList(orderDetailList);
        return orderParamDTO;
    }

    /**
     * 删除 提交订单后的购物车商品
     */
    public void removeCommitedProduct() {
        UserInfo userInfo = Authentication.getUserInfo();
        ShopCartDTO shopCartDTO = redisService.get(ShopCartKey.SHOP_CART_KEY, userInfo.getUnionId(), ShopCartDTO.class);
        List<StoreProductVO> storeProductList = shopCartDTO.getStoreProductList();
        storeProductList.forEach(storeProductVO -> storeProductVO.getProductList().removeIf(ProductVO::getCheck));
        storeProductList.removeIf(item -> CollectionUtils.isEmpty(item.getProductList()));
        if (CollectionUtils.isEmpty(storeProductList)) {
            redisService.delete(ShopCartKey.SHOP_CART_KEY, userInfo.getUnionId());
        } else {
            redisService.set(ShopCartKey.SHOP_CART_KEY, userInfo.getUnionId(), shopCartDTO);
        }
    }
}
